import React, {
  useEffect, useState, useCallback,
} from 'react';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import { makeStyles } from '@material-ui/core/styles';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
import copy from 'copy-to-clipboard';
import Icon from '../../../config/icons';
import {
  filterParentElement, updateHotkeyTip, hasClass,
  filterChildrenElement,
  // matchHotKey
} from '../libs/dom_utils';
import { setRangeByDomBeforeEnd } from '../libs/range_utils';
import LiteMenu from './LiteMenu';

const useStyles = makeStyles(({ spacing, palette }) => ({
  menuRoot: {
    minWidth: '224px',
    color: palette.type === 'dark' ? '#fff' : '#333',
  },
  menuItem: {
    display: 'flex',
    alignItems: 'center',
    height: '32px',
    width: '100%',
    position: 'relative',
  },
  subMenu: {
    position: 'absolute',
    top: '-6px',
    display: 'none',
    '&.active': {
      display: 'block',
    },
  },
  rightMenu: {
    right: 0,
    transform: 'translateX(100%)',
    paddingLeft: spacing(3),
  },
  leftMenu: {
    left: 0,
    transform: 'translateX(-100%)',
    paddingRight: spacing(3),
  },
  subMenuContainer: {
    color: palette.type === 'dark' ? '#fff' : '#333',
  },
  subMenuItem: {
    display: 'flex',
    border: 'none',
    textAlign: 'left',
    outline: 'none',
    fontSize: 14,
    padding: spacing(0, 2, 0, 1),
    height: 32,
    alignItems: 'center',
    width: '100%',
    backgroundColor: 'transparent',
    color: 'inherit',
    cursor: 'pointer',
    '&:hover,&.hover': {
      backgroundColor: '#006eff',
      color: '#fff',
    },
  },
  menuItemIcon: {
    borderRadius: 4,
    marginRight: spacing(1),
    width: 20,
    height: 24,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
  selectedIcon: {
    fontSize: 14,
  },
  menuName: {
    flex: '1',
    fontSize: '15px',
    letterSpacing: '1px',
    marginRight: spacing(2),
  },
  menuLine: {
    height: '1px',
    backgroundColor: '#d8d8d8',
    margin: spacing(0, 2),
  },
  iconArrow: {
    color: '#aaa',
    fontSize: '10px',
  },
  shortcut: {
    color: '#aaa',
    fontSize: '12px',
  },
}));

let currentCellElement;
let tableElement;
let clickTimer;
// 修复md表头分割线 | --- | --- | --- |   => | ----- | ----- | ----- |
function fixTableMd(md) {
  const textArr = md.split('\n');
  textArr[1] = textArr[1].replace(/---/g, '-----');
  return textArr.join('\n');
}

function TableMenu(props) {
  const classes = useStyles();

  const { intl } = props;

  const [menuPosition, setMenuPosition] = useState(undefined);
  const [subMenuPos, setSubMenuPos] = useState(null);
  const [align, setAlign] = useState('left');

  // function deleteTable() {
  //   if (tableElement) {
  //     tableElement.outerHTML = '';
  //     props.onSaveNote();
  //   }
  // }

  // function addRowAbove() {
  //   if (currentCellElement) {
  //     let rowHTML = '';
  //     for (let i = 0; i < currentCellElement.parentElement.childElementCount; i++) {
  //       rowHTML += '<td> </td>';
  //     }
  //     currentCellElement.parentElement.insertAdjacentHTML('beforebegin', `<tr>${rowHTML}</tr>`);
  //     setRangeByDomBeforeEnd(currentCellElement.parentElement.previousElementSibling.children[0]);
  //     props.onSaveNote();
  //   }
  // }

  // function addColBefore() {
  //   if (currentCellElement && tableElement) {
  //     let index = 0;
  //     let previousElement = currentCellElement.previousElementSibling;
  //     while (previousElement) {
  //       index++;
  //       previousElement = previousElement.previousElementSibling;
  //     }
  //     for (let i = 0; i < tableElement.rows.length; i++) {
  //       if (i === 0) {
  //         tableElement.rows[i].cells[index].insertAdjacentHTML('beforebegin', '<th> </th>');
  //       } else {
  //         tableElement.rows[i].cells[index].insertAdjacentHTML('beforebegin', '<td> </td>');
  //       }
  //     }
  //     props.onSaveNote();
  //   }
  // }

  // 通过触发editor.vditor快捷键实现表格操作功能
  const dispatchKey = useCallback((hotKey) => {
    if (props.editor?.vditor.ir.element) {
      const hotKeys = updateHotkeyTip(hotKey).split('-');
      let ctrlKey = false;
      let metaKey = false;
      if (hotKeys.length > 1 && (hotKeys[0] === 'ctrl' || hotKeys[0] === '⌘')) {
        if (window.wizApi.platform.isMac) {
          metaKey = true;
        } else {
          ctrlKey = true;
        }
      }
      const shiftKey = hotKeys.length > 2 && (hotKeys[1] === 'shift' || hotKeys[1] === '⇧');
      let key = (shiftKey ? hotKeys[2] : hotKeys[1]) || '-';
      if (shiftKey && key === '-' && !window.wizApi.platform.isMac) {
        key = '_';
      }
      const mockKeyboardEvent = new KeyboardEvent('keydown', {
        key, ctrlKey, metaKey, shiftKey,
      });
      props.editor.vditor.ir.element.dispatchEvent(mockKeyboardEvent);
    }
  }, [props.editor]);

  function getTableMd() {
    return fixTableMd(props.editor.current.htmlToMarkdown(tableElement.outerHTML));
  }

  function clickHandler(type, e) {
    if (!props.editor) return;
    if (clickTimer) {
      clearTimeout(clickTimer);
    }
    clickTimer = setTimeout(() => {
      //
      setRangeByDomBeforeEnd(currentCellElement);
      props.editor.current.resetCursor();

      switch (type) {
        case 'addRowAbove':
          props.editor.current.insertRowAbove();
          break;
        case 'addRowBelow':
          // dispatchKey('⌘-=');
          props.editor.current.insertRowBelow();
          break;
        case 'addColBefore':
          props.editor.current.insertColLeft();
          break;
        case 'addColAfter':
          // dispatchKey('⌘-⇧-=');
          props.editor.current.insertColRight();
          break;
        case 'alignLeft':
          // dispatchKey('⌘-⇧-L');
          props.editor.current.tableColAlignLeft();
          break;
        case 'alignCenter':
          // dispatchKey('⌘-⇧-C');
          props.editor.current.tableColAlignCenter();
          break;
        case 'alignRight':
          // dispatchKey('⌘-⇧-R');
          props.editor.current.tableColAlignRight();
          break;
        case 'deleteRow':
          // dispatchKey('⌘--');
          props.editor.current.removeTableRow();
          break;
        case 'deleteCol':
          // dispatchKey('⌘-⇧--');
          props.editor.current.removeTableCol();
          break;
        case 'deleteTable':
          props.editor.current.removeTable();
          break;
        case 'CpHtml':
          if (tableElement) {
            const copyHandler = (event) => {
              event.preventDefault();
              event.clipboardData.setData('text/plain', tableElement.outerHTML);
              event.clipboardData.setData('text/html', tableElement.outerHTML);
            };
            document.addEventListener('copy', copyHandler);
            copy();
            document.removeEventListener('copy', copyHandler);
          }
          break;
        case 'CpMd':
          if (props.editor && tableElement) {
            copy(getTableMd());
          }
          break;
        default:
          break;
      }
      clickTimer = null;
    }, 500);
    e.preventDefault();
    setMenuPosition(undefined);
    setSubMenuPos(null);
  }

  useEffect(() => {
    function handleShowSubMenu(e) {
      const ele = filterParentElement(e.target, document.body, (dom) => dom.getAttribute('data-type') === 'subMenu', true);
      if (ele && !subMenuPos) {
        const eleRect = ele.getBoundingClientRect();
        setSubMenuPos({
          left: eleRect.left + eleRect.width,
          top: eleRect.top,
        });
      } else if (!ele && !filterParentElement(e.target, document.body, (dom) => dom.getAttribute('data-type') === 'subMenuContainer', true) && subMenuPos) {
        setSubMenuPos(null);
      }
    }

    function handleMouseDown(e) {
      if (props.editor.current) {
        const ele = filterParentElement(
          e.target, props.editor.current.editor,
          (dom) => dom.tagName.toLocaleLowerCase() === 'table',
        );
        if (e.button === 2 && ele) {
          const parentId = filterParentElement(
            e.target,
            props.editor.current.editor,
            (dom) => dom.id && dom.className.includes('ag-cell-content'),
            true,
          )?.id;
          //
          const childrenId = filterChildrenElement(
            e.target,
            99,
            (dom) => dom.id && dom.className.includes('ag-cell-content'),
            true,
          )?.id;

          const updateKey = parentId || childrenId || null;
          //
          if (!updateKey) {
            console.warn('Cursor is not find.');
            return;
          }
          // 更新cursor
          props.editor.current.updateCursor({
            start: {
              key: updateKey,
              offset: 0,
            },
            end: {
              key: updateKey,
              offset: 0,
            },
          });
          //
          tableElement = ele;
          currentCellElement = filterParentElement(
            e.target,
            props.editor.current.editor,
            (dom) => ['th', 'td'].includes(dom.tagName?.toLocaleLowerCase()),
            true,
          );
          if (currentCellElement) {
            const currentCellElementAlign = getComputedStyle(currentCellElement, null).textAlign ?? 'left';
            if (currentCellElementAlign !== align) {
              setAlign(currentCellElementAlign);
            }
            props.editor.current.saveCursor();
            setMenuPosition({
              top: e.clientY,
              left: e.clientX,
            });
          }
          e.preventDefault();
        } else if (!filterParentElement(
          e.target, document.body,
          (dom) => hasClass(dom, classes.menuRoot),
          true,
        ) && menuPosition) {
          setMenuPosition(undefined);
        }
      }
    }

    // function handleKeyDown(e) {
    //   if (matchHotKey('⌘-Enter', e)) {
    //     dispatchKey('⌘-=');
    //     e.preventDefault();
    //   } else if (matchHotKey('⌘-⌥-Enter', e)) {
    //     dispatchKey('⌘-⇧-=');
    //     e.preventDefault();
    //   }
    // }

    // window.addEventListener('keydown', handleKeyDown);
    window.addEventListener('mouseover', handleShowSubMenu);
    window.addEventListener('mousedown', handleMouseDown);
    return () => {
      // window.removeEventListener('keydown', handleKeyDown);
      window.removeEventListener('mouseover', handleShowSubMenu);
      window.removeEventListener('mousedown', handleMouseDown);
    };
  }, [menuPosition, subMenuPos, props.editor, align, dispatchKey, classes.menuRoot]);

  const isHead = currentCellElement && currentCellElement.tagName.toLocaleLowerCase() === 'th';

  return (
    <Menu
      keepMounted
      open={Boolean(menuPosition)}
      anchorReference="anchorPosition"
      anchorPosition={menuPosition}
      classes={{
        list: classes.menuRoot,
      }}
    >
      {isHead ? '' : (
        <MenuItem onClick={(e) => clickHandler('addRowAbove', e)}>
          <div className={classes.menuItem}>
            <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuAddRowAbove' })}</div>
          </div>
        </MenuItem>
      )}
      <MenuItem onClick={(e) => clickHandler('addRowBelow', e)}>
        <div className={classes.menuItem}>
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuAddRowBelow' })}</div>
          <div className={classes.shortcut}>{updateHotkeyTip('⌘+Enter')}</div>
        </div>
      </MenuItem>
      <div className={classes.menuLine} />
      <MenuItem onClick={(e) => clickHandler('addColBefore', e)}>
        <div className={classes.menuItem}>
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuAddColBefore' })}</div>
        </div>
      </MenuItem>
      <MenuItem onClick={(e) => clickHandler('addColAfter', e)}>
        <div className={classes.menuItem}>
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuAddColAfter' })}</div>
          {/* <div className={classes.shortcut}>{updateHotkeyTip('⌘+⌥+Enter')}</div> */}
        </div>
      </MenuItem>
      <div className={classes.menuLine} />
      <MenuItem>
        <div
          className={classes.menuItem}
          data-type="subMenu"
        >
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuAlign' })}</div>
          <ArrowForwardIosIcon className={classes.iconArrow} />
          <LiteMenu position={subMenuPos ?? undefined} show={!!subMenuPos}>
            <div className={classes.subMenuContainer} data-type="subMenuContainer">
              <button type="button" className={classes.subMenuItem} onClick={(e) => clickHandler('alignLeft', e)}>
                <div className={classes.menuItemIcon}>
                  {align === 'left' && (<Icon.SelectedIcon className={classes.selectedIcon} />)}
                </div>
                <div>{intl.formatMessage({ id: 'tableMenuLeft' })}</div>
              </button>
              <button type="button" className={classes.subMenuItem} onClick={(e) => clickHandler('alignCenter', e)}>
                <div className={classes.menuItemIcon}>
                  {align === 'center' && (<Icon.SelectedIcon className={classes.selectedIcon} />)}
                </div>
                <div>{intl.formatMessage({ id: 'tableMenuCenter' })}</div>
              </button>
              <button type="button" className={classes.subMenuItem} onClick={(e) => clickHandler('alignRight', e)}>
                <div className={classes.menuItemIcon}>
                  {align === 'right' && (<Icon.SelectedIcon className={classes.selectedIcon} />)}
                </div>
                <div>{intl.formatMessage({ id: 'tableMenuRight' })}</div>
              </button>
            </div>
          </LiteMenu>
        </div>
      </MenuItem>
      <div className={classes.menuLine} />
      {isHead ? '' : (
        <MenuItem onClick={(e) => clickHandler('deleteRow', e)}>
          <div className={classes.menuItem}>
            <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuDeleteRow' })}</div>
          </div>
        </MenuItem>
      )}
      <MenuItem onClick={(e) => clickHandler('deleteCol', e)}>
        <div className={classes.menuItem}>
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuDeleteCol' })}</div>
        </div>
      </MenuItem>
      <MenuItem onClick={(e) => clickHandler('deleteTable', e)}>
        <div className={classes.menuItem}>
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuDeleteTable' })}</div>
        </div>
      </MenuItem>
      <div className={classes.menuLine} />
      <MenuItem onClick={(e) => clickHandler('CpHtml', e)}>
        <div className={classes.menuItem}>
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuCpHtml' })}</div>
        </div>
      </MenuItem>
      <MenuItem onClick={(e) => clickHandler('CpMd', e)}>
        <div className={classes.menuItem}>
          <div className={classes.menuName}>{intl.formatMessage({ id: 'tableMenuCpMd' })}</div>
        </div>
      </MenuItem>
    </Menu>
  );
}

TableMenu.propTypes = {
  intl: PropTypes.object.isRequired,
  editor: PropTypes.object,
  // onSaveNote: PropTypes.func.isRequired,
};

TableMenu.defaultProps = {
  editor: null,
};

export default injectIntl(TableMenu);
